//
//  main.m
//  C10_内存
//
//  Created by dllo on 15/10/19.
//  Copyright (c) 2015年 dllo. All rights reserved.
//

#import <Foundation/Foundation.h>

// 全局区和静态区的变量不用初始化,因为我们可以保证它已经清零
// 常量区和全局区(静态区)不在一个地方
// 静态区能保证所开的区域是清零的





int i = 0;

void test(void)
{
    
    for (i = 0; i < 6; i++) {
        printf("$");
    }
    
}


int main(int argc, const char * argv[]) {

//
//    for (i = 0; i < 5; i++) {
//        if (i >= 3) {
//            test();
//        }
//        printf("*");
//    }

//    int a = 0;
//    printf("栈区:%p\n", &a);
//    
//    int *p = malloc(sizeof(int));
//    printf("堆区:%p\n", p);
//    
//    static int b = 0;
//    printf("静态区:%p\n", &b);
//    
//    char *q = "qingChun";
//    printf("常量区:%p\n", q);
//    
//    printf("代码区:%p\n", test);
    
    
    // 堆内存分配函数
//    void *ret = malloc(开辟空间的大小(单位字节));
//    功能 : 在堆区开辟指定大小的空间
//    返回值 : 返回开辟的空间的首地址
//    参数 : 指定开辟空间的大小, 单位字节
    
//    在栈区开辟一个int类型大小的空间:
//    int a = 0;
//    
////    在堆区开辟一个int类型大小的空间:
////    int *p = malloc(4);
//    // 更好更兼容的写法
//    int *p = malloc(sizeof(int));
//    *p = 3;
//    
//    // 注意!!!堆内存的空间不会自动释放,需要手动释放,手动释放函数为free()
//    // 有一个malloc就要配对一个free函数
//    // free(需要释放空间的首地址)
//    free(p);
    
//    // int arr[5]
//    int *p = malloc(sizeof(int) * 5);
//    p[1] = 3;
//    *(p + 2) = 4;
//    
//    // int arr[5] 另一种方式(拓展)
//    int *pArr[5] = {NULL};
//    for (int i = 0; i < 5; i++) {
//        
//        pArr[i] = malloc(sizeof(int));
//        
//    }
//    // 注意
//    *(pArr[1]) = 3;
    
//    // 返回的空间当做什么类型变量用,取决于用什么类型指针去指向
//    // int a
//    int *p = malloc(sizeof(int));
//    // char c[4]
//    char *q = malloc(sizeof(int));
    
    
//    有一字符串,其中包含数字,提取其中的数字.要求动态分配内存保存
//    提示: 先计算出有几个数字,然后根据数字的个数来开辟空间.
    
//    char str[] = "qing2ch63un377n4";
//    
//    // 先记录字符串里有多少数字
//    int count = 0;
//    int n = 0;
//    for (int i = 0; i < strlen(str); i++) {
//        if (str[i] >= '0' && str[i] <= '9') {
//            count++;
//        }
//    }
//    
//    // 再去按记录结果动态开辟空间
//    
//    char *p = malloc(sizeof(char) * (count + 1));
    // 暂存空间首地址,防止p移动后找不回来
//    char * head = p;
//    //最后将数字挑选出来存入新开辟的空间
//    
//    for (int i = 0; i < strlen(str); i++) {
//        if (str[i] >= '0' && str[i] <= '9') {
//            p[n] = str[i];         //  *p = str[i];
//            n++;                   // p++;
//        }
//    }
//    不要忘记添加结束符
//    *p = '\0';
//    printf("%s\n", head);
//    for (int i = 0; i < count; i++) {
//        printf("%c ", p[i]);
//    }
    //    free(head);
//    p = NULL;
//    head = NULL;
    
    //    p = head;
    
//    输入3个单词,动态分配内存保存单词,并在最后输出
//    提示:定义一个指针数组保存数据 char * words[3] = {0};
    
//    char a[][3] = {0};
//
//    printf("请输入三个单词\n");
//    scanf("%s%s%s", &a[0][1], &a[0][2], &a[0][3]);
    
    char str[20] = {0};
    char *words[3] = {0};

    
    // 输入单词, 暂存到str中
    
    for (int i = 0; i < 3; i++) {
        
        // 输入字符串, 暂存到数组str中
        scanf("%s", str);
        // 计数字符串长度,以便动态开辟空间
        long len = strlen(str);
        // 开辟空间,注意用不同的指针去指向
        words[i] = malloc(sizeof(char) * (len + 1));
        // 将每次用户输入的字符串保存到动态开辟的空间中
        strcpy(words[i], str);     // 拷贝过来的能自动加'\0'
    }
    
    // 输出打印
    
    for (int i = 0; i < 3; i++) {
        printf("%s\n", words[i]);
        free(words[i]);
        words[i] = NULL;
    }
    
    
    // 分配n个size大小的空间,并且把该内存上的所有字节清零.
    // void *calloc(unsigned n, unsigned size);
    
    
    // 按给定的地址以及给定的大小重新分配
    // void *realloc(void *p, unsigned newSize);
    
    
    // 内存操作函数
    // 从s指向的内存开始初始化n个字节的内容为c
    //  void *memset(void *s , int c , size_t n)
//    int *p = malloc(sizeof(int) * 4);
//    p = memset(p, 0, sizeof(int) * 4);
//    
//    // 等效于上两句
//    int *q = calloc(4, sizeof(int));
    
    // 从source指向的内存开始拷贝到dest,拷贝n个字节
    // void *memcpy(void *dest,const void*source , size_t n)
    
    
    // 比较buf1和buf2指向的内存是否相同,比较count个字节
    // int memcmp(const void *buf1, const void *buf2, unsigned int count)
    
    
    
    
    
    
    
    return 0;
}
